package ArithmeticObjects;

import java.io.IOException;

import utils.ByteTree;

/**
 * Representing a single arithmetic object
 * @author Idan
 */
public abstract class Element{
	protected LargeNumber value; //the element's numeric value 

	
	/**
	 * @return the ByteTree representing the element
	 * @throws IOException 
	 */
	public abstract ByteTree getByteTree() throws IOException;
	
	/**
	 * @return the LargeNumber representing the Element's value
	 * if the Element is of a Tree type, returns null
	 */
	public LargeNumber getValue()
	{
		return value;
	}
	
	/**
	 * adds elements to the current element
	 * @param elementA the first mandatory element to add to the current element
	 * @param elements optional array of additional elements to add to the current element 
	 * @return the sum of the current element added to the given elements
	 * @throws Exception in case the addition operation failed
	 */
	public abstract Element add(Element elementA, Element...elements ) throws Exception;
	
	/**
	 * subtracts an element from the current element
	 * @param elementA the element to subtract from the current element
	 * @return the difference between the current element and the given elements
	 * @throws Exception in case the subtraction operation failed
	 */
	public abstract Element subtract(Element elementA) throws Exception;
	
	/**
	 * multiplies elements by the current element
	 * @param elementA the first mandatory element to multiply by the current element
	 * @param elements optional array of additional elements to multiply by the current element 
	 * @return the product of the current element multiplied by the given elements
	 * @throws Exception in case the multiplication operation failed
	 */
	public abstract Element multiply(Element elementA, Element...elements ) throws Exception;
	
	/**
	 * divides an element by the current element
	 * @param elementA the element to divide by the current element
	 * @return the division of the current element by the given element
	 * @throws Exception in case the division operation failed
	 */
	public abstract Element divide(Element elementA) throws Exception;
	
	/**
	 * raise the element by the power of exponent
	 * @param exponent the exponent to raise by
	 * @return the current element raised by the power of exponent
	 * @throws Exception in case the power operation failed
	 */
	public abstract Element power(Element exponent) throws Exception;
	
	/**
	 * calculates the additive inverse the the current object
	 * @return the additive inverse of the current element
	 * @throws Exception in case the inverse operation failed
	 */
	public abstract Element additiveInverse() throws Exception;
	
	/**
	 * compares the current element to the given one
	 * @param elementA the element to compare to
	 * @return 0 if the elements are the same and a number different than 0 otherwise
	 * @throws Exception in case the comparison operation failed
	 */
	public abstract int compareTo(Element elementA) throws Exception;
	
	/**
	 * returns the string representation of the element
	 */
	public abstract String toString(); 
}
